package projecto.pkgfinal;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class RepositorioPessoas {
    private  String path = "Pessoas.dat";
    private  File f = new File(path);
    private  ArrayList<Pessoa> listaPessoas = new ArrayList<Pessoa>();

    public  ArrayList<Pessoa> getListaPessoas() {
        return listaPessoas;
    }

    public  ArrayList<PessoaSistema> getListaPessoasComAcesso() {
      ArrayList<PessoaSistema> listaPessoasSistema = new ArrayList<PessoaSistema>();
      for(int i=0;i<listaPessoas.size();i++){
          if(listaPessoas.get(i) instanceof Medico || listaPessoas.get(i) instanceof Administrativo){
            listaPessoasSistema.add((PessoaSistema)listaPessoas.get(i));
          }
      }
      return listaPessoasSistema;
    }

    public  ArrayList<Medico> getListaMedicos() {
      ArrayList<Medico> medico = new ArrayList<Medico>();
      for(int i=0;i<listaPessoas.size();i++){
          if(listaPessoas.get(i) instanceof Medico ){
            medico.add((Medico)listaPessoas.get(i));
          }
      }
      return medico;
    }
    
    public  void carregarPessoasBIN() {
        try {
                //se o ficheiro existe..
                if (f.exists()) {
                        FileInputStream streamIn = new FileInputStream(f);
                        ObjectInputStream in = new ObjectInputStream(streamIn);
                        listaPessoas = (ArrayList<Pessoa>) in.readObject();
                }
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
                e.printStackTrace();
        } catch (ClassNotFoundException e) {
                e.printStackTrace();
        }

    }

    
    public void criarMedico(String numeroCedula, ArrayList<Especialidade> especialidades, String username, String password, String nomeProprio, int perfil, String apelido, char genero, ArrayList<Telefone> telefones, ArrayList<Morada> moradas, String bi, String nif, String nss){
        int id=proximoId();
        Medico medico = new Medico(numeroCedula, especialidades, username, password, nomeProprio, id, perfil, apelido, genero, telefones, moradas, bi, nif, nss);
        listaPessoas.add(medico);
    }
    public void criarAdministrativo( String username, String password,String nomeProprio, int perfil, String apelido, char genero, ArrayList<Telefone> telefones, ArrayList<Morada> moradas,  String bi, String nif, String nss){
        int id=proximoId();
        Administrativo administrativo = new Administrativo(username, password, nomeProprio, id, perfil, apelido, genero, telefones, moradas, bi, nif, nss);
        listaPessoas.add(administrativo);
    }
    public void criarUtente(String sistemaSaude,String nomeProprio, int perfil, String apelido, char genero, ArrayList<Telefone> telefones, ArrayList<Morada> moradas,  String bi, String nif, String nss){
        int id=proximoId();
        Utente utente = new Utente(sistemaSaude, nomeProprio, id, perfil, apelido, genero, telefones, moradas, bi, nif, nss);
        listaPessoas.add(utente);
    }
    
    public void actualizarMedico(int pessoaId,String numeroCedula, ArrayList<Especialidade> especialidades, String username, String password, String nomeProprio, String apelido, char genero, ArrayList<Telefone> telefones, ArrayList<Morada> moradas, String bi, String nif, String nss){
        int posicao=this.getPessoaIndex(pessoaId);
        Medico SenhorDoutor = (Medico) listaPessoas.get(posicao);
        SenhorDoutor.setNumeroCedula(numeroCedula);
        SenhorDoutor.setEspecialidades(especialidades);
        SenhorDoutor.setUsername(username);
        SenhorDoutor.setPassword(password);
        SenhorDoutor.setNomeProprio(nomeProprio);
        SenhorDoutor.setApelido(apelido);
        SenhorDoutor.setGenero(genero);
        SenhorDoutor.setTelefones(telefones);
        SenhorDoutor.setMoradas(moradas);
        SenhorDoutor.setNif(nif);
        SenhorDoutor.setBi(bi);
        SenhorDoutor.setNss(nss);        
    }
    
    public void actualizarAdministrativo(int pessoaId, String username, String password,String nomeProprio, String apelido, char genero, ArrayList<Telefone> telefones, ArrayList<Morada> moradas,  String bi, String nif, String nss ){
        int posicao=this.getPessoaIndex(pessoaId);
        Administrativo administrativo = (Administrativo) listaPessoas.get(posicao);
        administrativo.setUsername(username);
        administrativo.setPassword(password);
        administrativo.setNomeProprio(nomeProprio);
        administrativo.setApelido(apelido);
        administrativo.setGenero(genero);
        administrativo.setTelefones(telefones);
        administrativo.setMoradas(moradas);
        administrativo.setNif(nif);
        administrativo.setBi(bi);
        administrativo.setNss(nss);        
    }
    
    public void actualizarUtente(int pessoaId,String sistemaSaude,String nomeProprio, String apelido, char genero, ArrayList<Telefone> telefones, ArrayList<Morada> moradas,  String bi, String nif, String nss){
        int posicao=this.getPessoaIndex(pessoaId);
        Utente utente = (Utente) listaPessoas.get(posicao);

        utente.setNomeProprio(nomeProprio);
        utente.setApelido(apelido);
        utente.setGenero(genero);
        utente.setTelefones(telefones);
        utente.setMoradas(moradas);
        utente.setNif(nif);
        utente.setBi(bi);
        utente.setNss(nss);        
    }
    public  void gravarPessoasBIN() {
        if (listaPessoas.size() > 0) {
                try {
                        //se nao existir o ficheiro..cria-se
                        if (!f.exists())
                                f.createNewFile();

                        FileOutputStream streamOut = new FileOutputStream(path);
                        ObjectOutputStream out = new ObjectOutputStream(streamOut);
                        //escreve o conteudo da lista no ficheiro
                        out.writeObject(listaPessoas);
                        out.flush();
                        out.close();
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
    }
    /**
     *
     * @param db a base de dados de pessoas
     * @return  Retorna o proximo ID unico disponivel
     */
    public int proximoId(){
        if(listaPessoas.isEmpty())
            return 1;
        int ultimo = listaPessoas.get(listaPessoas.size()-1).getId();
        ultimo++;
        return ultimo;
        
    }
    
     public int getPessoaIndex(int pessoaId){
         if (getListaPessoas().size() > 0) {
			for (int i = 0; i < getListaPessoas().size(); i++) {
				if (pessoaId == getListaPessoas().get(i).getId()) {
					return i;
				}
			}
			return 0;
		}
		return 0;
     }
     
     public boolean existePessoasParaLogin(){
     if(this.getListaPessoasComAcesso().size()>0)
         return true;
     else
         return false;
     }
     
     public boolean verificarLogin(String username, String password){
        for(int i=0;i<this.getListaPessoasComAcesso().size();i++){
            if(this.getListaPessoasComAcesso().get(i).getUsername().equals(username) && this.getListaPessoasComAcesso().get(i).getPassword().equals(password) ){
                int perfil = this.getListaPessoasComAcesso().get(i).getPerfil();
                int id = this.getListaPessoasComAcesso().get(i).getId();
                Operador.perfil=perfil;
                Operador.id=id;
                return true;  
                
            }
        }
        return false;
        
    }

     public void listarPessoas(String tipo){
         boolean flag=false;
        if(this.getListaPessoas().size()>0){
            for(Pessoa pessoa: this.getListaPessoas()){
                if(tipo.equals(String.valueOf(pessoa.getPerfil()))){
                    System.out.print(pessoa.toString());
                    flag=true;
                }
            }
            if(!flag)
                System.out.print("Não existem pessoas deste perfil para listar\n");
        }else{
            System.out.print("Não existem pessoas em sistema\n");
        }
     }
     public void listarNomePessoasComId(String tipo){
         boolean flag=false;
        if(this.getListaPessoas().size()>0){
            for(Pessoa pessoa: this.getListaPessoas()){
                if(tipo.equals(String.valueOf(pessoa.getPerfil()))){
                    System.out.println("\t"+pessoa.getId() +" - "+ pessoa.getNomeProprio()+" "+pessoa.getApelido()+"\n");
                    flag=true;
                }
            }
            if(!flag)
                System.out.print("Não existem pessoas deste perfil para listar\n");
        }else{
            System.out.print("Não existem pessoas em sistema\n");
        }
     }
     public void listarNomePessoasComId(){
        if(this.getListaPessoas().size()>0){
            for(Pessoa pessoa: this.getListaPessoas()){
                    System.out.println("\t"+pessoa.getId() +" - "+ pessoa.getNomeProprio()+" "+pessoa.getApelido()+"\n");
            }
        }else{
            System.out.print("Não existem pessoas em sistema\n");
        }
     }

     public void listarPessoas(){
        if(this.getListaPessoas().size()>0){
            for(Pessoa pessoa: this.getListaPessoas()){
                    System.out.println(pessoa.toString());
            }
        }else{
            System.out.print("Não existem pessoas em sistema\n");
        }
     }
     
     public void listarPessoa(int pessoaId,String tipo){        
        int posicao = this.getPessoaIndex(pessoaId);
        if (pessoaId == this.getListaPessoas().get(posicao).getId() && tipo.equals( String.valueOf(this.getListaPessoas().get(posicao).getPerfil()))) {
            System.out.println("\nREGISTO ENCONTRADO!\n");
            System.out.println(this.getListaPessoas().get(posicao).toString());
        } else
            System.out.println("\nREGISTO NAO ENCONTRADO!\n");
     
     }
     
     public void listarMedicosPorEspecialidade(int codigoEspecialidade){
         boolean flag=false;
        for(int i=0;i<this.getListaMedicos().size();i++){
            for(int z=0;z<this.getListaMedicos().get(i).getEspecialidades().size();z++){
                if(this.getListaMedicos().get(i).getEspecialidades().get(z).getCodigo()==codigoEspecialidade){
                    System.out.println(this.getListaMedicos().get(i).toString());
                    flag=true;
                }
            }
        }
        if(!flag)
            System.out.println("\nNão foram encontrados médicos com essa especialidade!\n");     
     }
     public void listarNomePessoa(String tipo){
     if(this.getListaPessoas().size()>0){
            for(Pessoa pessoa: this.getListaPessoas()){
                if(tipo.equals(String.valueOf(pessoa.getPerfil())))
                    System.out.println(pessoa.getId() + " - " + pessoa.getNomeProprio() + " "+ pessoa.getApelido());
            }
        }else{
            System.out.print("Não existem pessoas em sistema\n");
        }
    
     }
     public boolean temEspecialidade(int pessoaId,int idEspecialidade){        
        int posicao = this.getPessoaIndex(pessoaId);
        Medico SrDoutor = (Medico)this.getListaPessoas().get(posicao);
        if (SrDoutor.getEspecialidades().size()>0) {
             for(int i=0;i<SrDoutor.getEspecialidades().size();i++){
                 if(SrDoutor.getEspecialidades().get(i).getCodigo()==idEspecialidade)
                     return false;                    
             }
             return false;
        } else
            return false;
     }
     public boolean temEspecialidade(int idEspecialidade){
         
       for(int i=0;i<this.getListaPessoas().size();i++){
           if(this.getListaPessoas().get(i) instanceof Medico){
               Medico SrDoutor = (Medico)this.getListaPessoas().get(i);
               for(int z=0;z<SrDoutor.getEspecialidades().size()-1;z++){
                   if (SrDoutor.getEspecialidades().get(z).getCodigo()==idEspecialidade) {
                       return true;                    
                   }
               }
           }
       } 
        return false;
        
     }
     public void listarPessoa(int pessoaId){        
        int posicao = this.getPessoaIndex(pessoaId);
        if (pessoaId == this.getListaPessoas().get(posicao).getId()) {
            System.out.println("\nREGISTO ENCONTRADO!\n");
            System.out.println(this.getListaPessoas().get(posicao).toString());
        } else
            System.out.println("\nREGISTO NAO ENCONTRADO!\n");
     
     }
     public boolean existePessoa(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         if (pessoaId == this.getListaPessoas().get(posicao).getId()) {
             return true;
         }else
             return false;
     
     }
     public boolean existePessoa(Integer tipo,Integer pessoaId){
        if(this.getListaPessoas().size()>0){
            for(Pessoa pessoa: this.getListaPessoas()){
                if(tipo.equals(pessoa.getPerfil()) && pessoaId.equals(pessoa.getId())){
                    return true;
                }
            }
            return false;
        }else{
            return false;
        }
     }
     public boolean existeTipoPessoa(String tipo){
        if(this.getListaPessoas().size()>0){
            for(Pessoa pessoa: this.getListaPessoas()){
                if(tipo.equals(String.valueOf(pessoa.getPerfil()))){
                    return true;
                }
            }
            return false;
        }else{
            return false;
        }
     }
     public boolean pessoaTemPerfil(int pessoaId,String perfil){
         int posicao = this.getPessoaIndex(pessoaId);
         if (perfil.equals(String.valueOf(this.getListaPessoas().get(posicao).getPerfil())))
             return true;
         else
             return false;
     
     }
     public void apagarPessoa(int pessoaId,Integer tipo){
         int posicao = this.getPessoaIndex(pessoaId);
         if(posicao>=0){
             //Verifica se o id do operador do sistema é o mesmo que se está a apagar
             if(pessoaId!=Operador.id){
                 if(tipo.equals(listaPessoas.get(posicao).getPerfil())){
                     System.out.println(tipo);
                     switch (tipo){
                         case 1:
                             if(!Consultorio.dbConsultas.existeConsulta(Integer.valueOf(Pessoa.TIPOMEDICO[0]), pessoaId)){
                                listaPessoas.remove(posicao);
                                System.out.println("\nREGISTO DO MÉDICO APAGADO!\n");
                             }else
                                 System.out.println("\nExistem consultas que este médico tem de realizar, não pode pagar o registo.\n");
                         break;
                             
                         case 2:
                             if(!Consultorio.dbConsultas.existeConsulta(Integer.valueOf(Pessoa.TIPOUTENTE[0]), pessoaId)){
                                listaPessoas.remove(posicao);
                                System.out.println("\nREGISTO DO UTENTE APAGADO!\n");
                             }else 
                                System.out.println("\nExistem consultas onde este utente está inscrito, não pode pagar o registo.\n");
                         break;
                         case 3:
                                 listaPessoas.remove(posicao);
                                 System.out.println("\nREGISTO DO ADMINISTRATIVO APAGADO!\n");
                         break;
                     } 
                 }else{
                    System.out.println("\nA pessoa encontrada não corresponde ao perfil que pretende apagar!\n");
                 }
            }else
                 System.out.println("\nNão pode apagar o seu próprio registo!\n");
         }else{
            System.out.println("\nREGISTO NÃO ENCONTRADO!\n");
         }
     }
     //GET's
     public Pessoa getPessoa(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao); 
     }
     public String getNomeProprio(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getNomeProprio(); 
     }
     public String getApelido(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getApelido(); 
     }
     public char getGenero(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getGenero(); 
     }
     public String getNif(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getNif(); 
     }
     public String getNss(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getNss(); 
     }
     public String getBi(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getBi(); 
     }
     public int getNumeroMoradas(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getMoradas().size(); 
     }
     public int getNumeroTelefones(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getTelefones().size(); 
     }
     public int getPorta(int pessoaId,int i){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getMoradas().get(i).getPorta(); 
     }
     public String getRua(int pessoaId,int indexMorada){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getMoradas().get(indexMorada).getRua(); 
     }
     public String getCodigoPostal(int pessoaId,int indexMorada){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getMoradas().get(indexMorada).getCodigoPostal(); 
     }
     public String getLocalidade(int pessoaId,int indexMorada){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getMoradas().get(indexMorada).getLocalidade(); 
     }
     public short getIndicativoPais(int pessoaId,int indexTelefone){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getTelefones().get(indexTelefone).getIndicativoPais(); 
     }
     public short getIndicativoDistrito(int pessoaId,int indexTelefone){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getTelefones().get(indexTelefone).getIndicativoDistrito(); 
     }
     public int getNumeroTelefone(int pessoaId,int indexTelefone){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getTelefones().get(indexTelefone).getNumero(); 
     }
     public int getPerfil(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getPerfil(); 
     }
     public String getNumeroCedula(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         Medico senhorDoutor = (Medico) this.getListaPessoas().get(posicao);
         if(senhorDoutor.getNumeroCedula().isEmpty())
             return ("Não tem");
         else
             return senhorDoutor.getNumeroCedula();
     }
     public int getNumeroEspecialidades(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         Medico senhorDoutor = (Medico) this.getListaPessoas().get(posicao);
         return senhorDoutor.getEspecialidades().size();
     }
     public int getCodigoEspecialidade(int pessoaId,int indexEspecialidade){
         int posicao = this.getPessoaIndex(pessoaId);
         Medico senhorDoutor = (Medico) this.getListaPessoas().get(posicao);
         return senhorDoutor.getEspecialidades().get(indexEspecialidade).getCodigo();
     }
     public void getEspecialidades(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         Medico senhorDoutor = (Medico) this.getListaPessoas().get(posicao);
         if(senhorDoutor.getEspecialidades().size()>0){
            System.out.println(senhorDoutor.getEspecialidades().toString());
         }else{
            System.out.println("Não tem especialidades");
         }
     }
     public String getNomeEspecialidade(int pessoaId,int indexEspecialidade){
         int posicao = this.getPessoaIndex(pessoaId);
         Medico senhorDoutor = (Medico) this.getListaPessoas().get(posicao);
         return senhorDoutor.getEspecialidades().get(indexEspecialidade).getNome();
     }
     public String getUsername(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         PessoaSistema pessoaSistema = (PessoaSistema) this.getListaPessoas().get(posicao);
         return pessoaSistema.getUsername();
     }
     public String getPassword(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         PessoaSistema pessoaSistema = (PessoaSistema) this.getListaPessoas().get(posicao);
         return pessoaSistema.getPassword();
     }
     public String getSistemaSaude(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         Utente utente = (Utente) this.getListaPessoas().get(posicao);
         return utente.getSistemaSaude();
     }
     public ArrayList<Morada> getMoradas(int pessoaId){
         int posicao = this.getPessoaIndex(pessoaId);
         return this.getListaPessoas().get(posicao).getMoradas();
     }
     public void apagarMorada(int pessoaId,int index){
         int posicao = this.getPessoaIndex(pessoaId);
         this.getListaPessoas().get(posicao).getMoradas().remove(index) ;
     }
     public void adicionarMorada(int pessoaId,int porta, String rua, String codigoPostal, String localidade){
         int posicao = this.getPessoaIndex(pessoaId);
         Morada morada = new Morada(rua,porta,codigoPostal,localidade);
         this.getListaPessoas().get(posicao).getMoradas().add(morada) ;
     }
}
